﻿/* 
 *  Unplugged LINQ to SQL Generator
 *  
 *  Authors: José Marcenaro - josem@tercerplaneta.com
 *           Benjamín Eidelman - benjamine@tercerplaneta.com
 *  Tercer Planeta - http://www.tercerplaneta.com
 */

#region Usage
/* Usage:
 * 
 * Add a .dbml file to a project and set:
 *  	Custom Tool: ULinqToSQLGenerator
 */
#endregion Usage

using System;
using System.Collections.Generic;
using System.Linq;
using CustomToolGenerator;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace ULinq.GenTools
{
    /// <summary>
    /// This class defines and register the custom tool
    /// The actual work is done by <see cref="ULinqCodeGenerator"/>
    /// </summary>
    [Guid(ULinqCustomTool.Guid)]
    [ComVisible(true)]
    public class ULinqCustomTool : BaseCodeGeneratorWithSite
    {
        public const string Guid = "2F7DCF30-5BB5-43bd-876B-C10F426DBEEE";
        const string KeyPathFormat = @"SOFTWARE\Microsoft\VisualStudio\{0}\Generators\{1}\{2}";
        const string CSGeneratorCategory = "{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}";
        const string VBGeneratorCategory = "{164B10B9-B200-11D0-8C61-00A0C91E29D5}";
        const string customToolName = "ULinqToSQLGenerator";
        const string customToolDescription = "ULinqToSQL Code Generator";

        /// <summary>
        /// Override default extension with .designer prefix
        /// </summary>
        /// <returns></returns>
        public override string GetDefaultExtension()
        {
            return ".designer" + base.GetDefaultExtension();
        }

        /// <summary>
        /// Method called by BaseCodeGeneratorWithSite to generate the code
        /// </summary>
        protected override byte[] GenerateCode(string inputFileName, string inputFileContent)
        {
            ULinqCodeGenerator generator = new ULinqCodeGenerator(this.CodeProvider);

            // the generator class does the real work
            string result = generator.BuildCode(base.FileNameSpace, inputFileName, inputFileContent);

            return System.Text.Encoding.UTF8.GetBytes(result);
        }

        #region Registration tasks
        /// <summary>
        /// Registers the custom tool
        /// </summary>
        [ComRegisterFunction]
        public static void RegisterCom(Type type)
        {
            AddToRegistry("9.0", CSGeneratorCategory);
            AddToRegistry("9.0", VBGeneratorCategory);
        }

        /// <summary>
        /// Unregisters the custom tool
        /// </summary>
        [ComUnregisterFunction]
        public static void UnregisterCom(Type type)
        {
            RemoveFromRegistry("9.0", CSGeneratorCategory);
            RemoveFromRegistry("9.0", VBGeneratorCategory);
        }

        /// <summary>
        /// Add registry entries for the custom tool
        /// </summary>
        private static void AddToRegistry(string version, string category)
        {
            string path = String.Format(KeyPathFormat, version, category, customToolName);
            using (RegistryKey key = Registry.LocalMachine.CreateSubKey(path))
            {
                key.SetValue("", customToolDescription);
                key.SetValue("CLSID", "{" + Guid + "}");
                key.SetValue("GeneratesDesignTimeSource", 1);
            }
        }
        /// <summary>
        /// Remove registry entries for the custom tool
        /// </summary>
        private static void RemoveFromRegistry(string version, string category)
        {
            string path = String.Format(KeyPathFormat, version, category, customToolName);
            Registry.LocalMachine.DeleteSubKey(path, false);
        }

        #endregion
    }
}
